package proc

import (
	"context"
)

// New 创建一个命令
func New() *Cmd {
	return &Cmd{}
}

// Context 使用上下文Context对象创建一个命令
func Context(ctx context.Context) *Cmd {
	return New().Context(ctx)
}

// Command 使用程序路径和参数创建一个命令, 类似 exec.Command
func Command(path string, args ...string) *Cmd {
	return New().Command(path, args...)
}

// CommandContext 使用程序路径和参数创建一个命令 exec.CommandContext
func CommandContext(ctx context.Context, path string, args ...string) *Cmd {
	return Context(ctx).Command(path, args...)
}

// Command 设置命令的执行路径(绝对路径或者相对DIR路径或者PATH)和参数
func (c *Cmd) Command(path string, args ...string) *Cmd {
	if c == nil {
		return c
	}
	c.path = path
	c.args = args
	return c
}

// Name 设置命令名称(标识)，用于友好识别
func (c *Cmd) Name(name string) *Cmd {
	if c == nil {
		return c
	}
	c.name = name
	return c
}

// DIR 设置工作目录
func (c *Cmd) DIR(dir string) *Cmd {
	if c == nil {
		return c
	}
	c.dir = dir
	return c
}

// Env 设置环境变量
func (c *Cmd) Env(env []string) *Cmd {
	if c == nil {
		return c
	}
	c.env = env
	return c
}

// OnStatusChanged 设置状态变更监听
func (c *Cmd) OnStatusChanged(onStatusChanged StatusChangedFunc) *Cmd {
	if c == nil {
		return c
	}
	c.onStatusChanged = onStatusChanged
	return c
}

// QuitWith 设置退出信道
func (c *Cmd) QuitWith(quit <-chan struct{}) *Cmd {
	if c == nil {
		return c
	}
	c.quit = quit
	return c
}

// Context 设置上下文对象(控制退出)
func (c *Cmd) Context(ctx context.Context) *Cmd {
	if ctx != nil {
		return c.QuitWith(ctx.Done())
	}
	return c
}

// UseWindowsLegacyProcessStrategy 使用传统进程管理(windows)
func (c *Cmd) UseWindowsLegacyProcessStrategy(yes ...bool) *Cmd {
	if c == nil {
		return c
	}
	c.useWindowsLegacyProcessStrategy = getBool(yes)
	return c
}

// Background 后台运行(不阻断 Start 方法)
func (c *Cmd) Background(background ...bool) *Cmd {
	if c == nil {
		return c
	}
	c.bg = getBool(background)
	return c
}

// Verbose 打印执行的命令
func (c *Cmd) Verbose(verbose ...bool) *Cmd {
	if c == nil {
		return c
	}
	c.verbose = getBool(verbose)
	return c
}

// OnExit 退出时执行
func (c *Cmd) OnExit(onExit ...func()) *Cmd {
	c.onExit = append(c.onExit, onExit...)
	return c
}

func getBool(yes []bool) bool {
	return len(yes) == 0 || yes[0]
}
